package cre.hiber.util;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.apache.tika.Tika;
import org.apache.tika.metadata.Metadata;
import org.wltea.analyzer.lucene.IKAnalyzer;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

/**
 * Created by CreGu on 2016/7/25.
 */
public class TikaUtils {
    protected static final org.slf4j.Logger log = org.slf4j.LoggerFactory
            .getLogger(TikaUtils.class);

    public final static String ARTICLE_CONTENT = "fileContent";
    public final static String ARTICLE_NAME = "fileName";
    public final static String ARTICLE_PATH = "filePath";

    private static IndexWriter indexWriter;
    private static IndexSearcher indexSearcher;
    private static Analyzer analyzer = new IKAnalyzer();

    public static List searchIndex(String query, String[] fields, int num, String indexBase) {
        MultiFieldQueryParser parser = new MultiFieldQueryParser(
                Version.LUCENE_36, fields, analyzer);
        try {
            Query luceneQuery = parser.parse(query);
            IndexSearcher indexSearcher = getIndexSearcher(indexBase);
            TopDocs topDocs =
                    indexSearcher.search(luceneQuery, num);
            ScoreDoc[] docs = topDocs.scoreDocs;

            for (ScoreDoc doc : docs) {
                Document document = indexSearcher.doc(doc.doc);
                System.out.println(document);

                List<Fieldable> fields1 = document.getFields();
                for (Fieldable field : fields1) {
                    System.out.println(field);
                }

                System.out.println(document.get(ARTICLE_CONTENT));
                ;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * @param indexBase
     * @return
     */
    public static IndexSearcher getIndexSearcher(String indexBase) {
        // 单例
        if (indexSearcher == null) {
            synchronized (TikaUtils.class) {
                try {
                    File file = new File(indexBase);
                    FSDirectory directory = FSDirectory.open(file);

                    IndexReader indexReader = IndexReader.open(directory);
                    indexSearcher = new IndexSearcher(indexReader);
                } catch (IOException e) {
                    log.info("获取IndexSearcher异常：" + e.getMessage());
                    e.printStackTrace();
                }
            }
        }
        return indexSearcher;
    }

    /**
     * 创建索引
     *
     * @param file
     * @param indexBase
     * @return
     */
    public static boolean createIndex(File file, String indexBase) {
        IndexWriter indexWriter = getIndexWriter(indexBase);

        if (!createIndex(indexWriter, file)) return false;
        try {
            // 提交，在这里提交保证程序的原子性
            indexWriter.commit();
            log.info("文件索引创建成功：" + file.getName() + " " + file.getAbsolutePath());
        } catch (Exception e) {
            log.info("文件索引创建之后提交失败：" + e.getMessage());
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * @param indexBase
     * @return
     */
    public static IndexWriter getIndexWriter(String indexBase) {
        if (indexWriter == null) {
            synchronized (TikaUtils.class) {
                try {
                    File file = new File(indexBase);
                    if (!file.exists()) file.mkdir();

                    FSDirectory directory = FSDirectory.open(file);
                    IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_36,
                            analyzer);

                    indexWriter = new IndexWriter(directory, conf);
                } catch (IOException e) {
                    e.printStackTrace();
                    log.info("获取IndexWriter异常：" + e.getMessage());
                }
            }
        }
        return indexWriter;
    }

    private static boolean createIndex(IndexWriter indexWriter, File file) {
        if (file == null || !file.exists() || !file.canRead()) return false;
        if (file.isDirectory()) {
            // 文件夹
            File[] files = file.listFiles();
            for (File f : files) {
                createIndex(indexWriter, f);
            }
        } else {
            // 文件
            try {
                Document doc = new Document();
                Tika tika = new Tika();

                Metadata metadata = new Metadata();
                metadata.add(Metadata.CONTENT_ENCODING, "utf-8");

                String infos = tika.parseToString(new FileInputStream(file), metadata);
                System.out.println(infos);
//                创建索引，除去zip
//                doc.add(new Field(ARTICLE_CONTENT, infos, Store.NO, Index.ANALYZED));
                doc.add(new Field(ARTICLE_NAME, file.getName(), Store.YES, Index.ANALYZED));
                doc.add(new Field(ARTICLE_PATH, file.getAbsolutePath(), Store.YES, Index.NO));
                doc.add(new Field("name", infos, Store.NO, Index.ANALYZED));

                indexWriter.addDocument(doc);

                log.info("正在加载文件索引：" + file.getName() + " " + file.getAbsolutePath());
            } catch (Exception e) {
                log.info("索引创建失败：" + e.getMessage());
                e.printStackTrace();
                return false;
            } finally {

            }
        }
        return true;
    }

    public static void main(String[] args) {
        String filePath = "D:/tikatest/test3.doc";
        File file = new File(filePath);
        String indexBase = "D:\\lucene\\indexs\\cre.hiber.domain.User";//"C:\\Users\\CreGu\\.v1_index";

        TikaUtils.createIndex(file, indexBase);
//        List<Map<String, String>> res = TikaUtils.readIndex("study", 10, indexBase);
//
//        for (Map<String, String> r : res) {
//
//            System.out.println(r);
//        }
    }
}
